#ifndef ALGA_AMD_DCE6_DCE6_H
#define ALGA_AMD_DCE6_DCE6_H
/*
  author Sylvain Bertrand <sylvain.bertrand@gmail.com>
  Protected by linux GNU GPLv2
  Copyright 2012-2014
*/

#define CRTCS_N_MAX 6
#define DCE6_DISPS_MAX (CRTCS_N_MAX * 128)
#define HPDS_N 6

#ifdef __KERNEL__
#define DCE6_ERR 1000

struct dce_db_fb {
	u64 primary;
	u64 secondary;
	u32 pitch;
	char mode[sizeof("hhhhxvvvv@vvv")];
	char pixel_fmt[sizeof("ARGB2101010")];
};

/* major programming functions: do lock dce state */
struct dce6;
#include <alga/amd/dce6/dce6_dev.h>
struct dce6 *dce6_alloc(struct dce6_dev *ddev);
long dce6_init_once(struct dce6 *dce);
long dce6_init(struct dce6 *dce, u32 dmif_addr_cfg);
long dce6_cold_plug(struct dce6 *dce);
long dce6_sysfs_cold_register(struct dce6 *dce, struct device *parent_char_dev);
long dce6_sysfs_unregister(struct dce6 *dce);
void dce6_edid_free(struct dce6 *dce);
void dce6_i2c_cleanup(struct dce6 *dce);
void dce6_off(struct dce6 *dce);
long dce6_sink_mode_set(struct dce6 *dce, u8 i, struct dce_db_fb *db_fb);
long dce6_dp_dpm(struct dce6 *dce, u8 i);
long dce6_edid(struct dce6 *dce, u8 i, void *edid, u16 edid_sz);
long dce6_pf(struct dce6 *dce, u8 i,
	void (*notify)(u8 i, u32 vblanks_n, struct timespec monotonic_raw_tp,
						void *data), void *data);
void dce6_pf_cancel_all(struct dce6 *dce);
/* irq thread */
long dce6_irqs_thd(struct dce6 *dce);

/* hard interrupt context: ack and tag hpd/pf events */
void dce6_hpd_irq(struct dce6 *dce, u8 hpd);
void dce6_pf_irq(struct dce6 *dce, u8 i,
			struct timespec monotonic_raw_tp);

/* suspend related */
void dce6_hpd_dev_registration_lock(struct dce6 *dce);
void dce6_hpd_dev_registration_unlock(struct dce6 *dce);

/* direct hardware access */
void dce6_vga_off(struct dce6 *dce);
void dce6_irqs_ack(struct dce6 *dce);
void dce6_intrs_reset(struct dce6 *dce);
void dce6_hpds_intr_ena(struct dce6 *dce);

/* direct atombios access */
long dce6_crtcs_shutdown(struct dce6 *dce);
#endif
#endif
